import lesson
import pygtk
pygtk.require('2.0')
import gtk
import typing
import sound
import os
import time
import memory
import pygame
import threading
import random

#Should remain constant
lineLength = 64
undefinedInt = -1
undefinedString = ""
undefinedArray = []

TYPING_ROOT = os.path.dirname(os.path.abspath(__file__))
while(os.path.isfile(TYPING_ROOT)):
    TYPING_ROOT = os.path.dirname(TYPING_ROOT)
IMAGE_SOURCE = TYPING_ROOT + os.sep + "images" + os.sep + "lessons"
   
class LessonGame(gtk.EventBox):

    #Initializes a window for the lesson game
    #Setting variables to un-set values
    #Creating a sound player, etc.
    def __init__(self, window, lessons, endSounds):
        super(LessonGame, self).__init__()

        self.win = window

        #Control if we play sounds at the end of a word.
        #We don't do so in the sub-class, assessmentMode
        self.playEnds = endSounds
        
        self.container = gtk.HBox()
        self.container.show()
        self.add(self.container)

        #Build the final reward screen, but keep it hidden for if the user completes the lesson.
        self.makeRewards()
        self.container.add(self.rewardscreen)
        
        #Load up any dipthongs sounds to play
        self.loadDipthongs()

        #Create a table to hold all the elements        
        self.table = gtk.Table(10, 10, True)
        self.table.set_row_spacings(10)
        self.table.set_col_spacings(10)

        self.container.add(self.table)
    
        #Load up the lesson file
        self.lessonPlan = lessons

        #Load up the words learned for this player.
        self.membox = gtk.HBox(False, 0)
        self.memory = []
        self.memoryLabels = {}

        self.memoryFiles = memory.Memory(self.memoryCallback, self.membox, self.memoryLabels, self.lessonPlan)
        keys = self.memoryLabels.keys()
        for x in keys:
            self.memory.append(self.memoryLabels[x].get_text())
        
        #load up all other self variables with some "undefined" values        
        self.wordNum = undefinedInt
        self.currentWord = undefinedString
        self.inputString = undefinedString
        self.currChar = undefinedInt
        self.goThree = False
        self.makeString = True
        self.reviewString = undefinedString
        

        #---------
        #Create the window
        self.table.show()
        
        displayWindow = gtk.ScrolledWindow()
        self.create_text_prompt(displayWindow)

        self.table.attach(self.membox, 0, 9, 0, 1)
        EBox = gtk.EventBox()
        self.membox.pack_start(EBox, False, True, 0)
        EBox.show()
        self.membox.show()
        

        #Place the objects in the vbox for display        
        self.workframe = gtk.Frame()
        self.workframe.add(displayWindow)
        self.workframe.show()
        self.table.attach(self.workframe, 4, 10, 1, 4)
        
        #Place an image box for display
        self.imagetext = gtk.TextView()    
        self.imagetext.set_cursor_visible(False)
        self.imagetext.set_justification(gtk.JUSTIFY_CENTER)
        self.imagetext.set_editable(False)

        #Create tags for the image display window to increase size, color        
        sizetag = gtk.TextTag("size")
        sizetag.set_property("size-points", 24)
        self.imagetext.get_buffer().get_tag_table().add(sizetag)
        colortag = gtk.TextTag("color")
        colortag.set_property("foreground", "blue")
        self.imagetext.get_buffer().get_tag_table().add(colortag)

        #Attach the image frame.        
        self.imageframe = gtk.Frame()
        self.imageframe.add(self.imagetext)
        self.imageframe.show()
        self.table.attach(self.imageframe, 0, 4, 1, 4)

        #Create a button to go back.        
        backbutton = gtk.Button()
        image = gtk.Image()
        image.set_from_file(TYPING_ROOT + os.sep + "images" + os.sep + "backbutton.gif")
        image.show()
        backbutton.set_image(image)
        backbutton.show() 
        self.table.attach(backbutton, 0, 1, 4, 5)
        backbutton.connect("clicked", self.back) 

        #Create a help button, to highlight the image and letter if needed.        
        self.helpbutton = gtk.Button()
        image = gtk.Image()
        pixbuf = gtk.gdk.pixbuf_new_from_file(IMAGE_SOURCE + os.sep + "helpbutton.png").scale_simple(25, 25, gtk.gdk.INTERP_BILINEAR)
        image.set_from_pixbuf(pixbuf)
        self.helpbutton.set_image(image)
        self.table.attach(self.helpbutton, 9, 10, 4, 5)
        self.helpbutton.connect("clicked", self.helpdisplay)
        self.helpbutton.show()

        #Create a bar to keep track of user progress over the course of the lesson
        self.progressBar = gtk.ProgressBar()
        self.progressBar.set_fraction(0);
        self.table.attach(self.progressBar, 1, 9, 4, 5)
        self.progressBar.show()

        #Load up a keyboard and place it in the window        
        self.keyboard = typing.Typing(self)
        self.table.attach(self.keyboard, 0, 10, 5, 10)

        # Display the keyboard and the window for the current word
        self.keyboard.show()
        displayWindow.show()

        #Link to checking input
        self.keyboard_trigger = self.connect("key-press-event", self.isRight)
        self.handler_block(self.keyboard_trigger)

    #Displays help for the current word.  Goes through each letter, highlight it in the output and keyboard
    def helpdisplay(self, widget):
        #Prevent user from typing while displaying the help.
        self.handler_block(self.keyboard_trigger)
        length = len(self.inputString)        
        helpcolor = self.textbuffer.get_tag_table().lookup("helpcolor")
        #Highlight letters from what we're on to the end.
        #Wait at each point to give the user time to get the help
        for i in range(self.currChar, length):
            self.textbuffer.apply_tag(helpcolor, self.textbuffer.get_iter_at_offset(i), self.textbuffer.get_iter_at_offset(i+1))
            self.keyboard.highlightkey(self.inputString[i])
            while gtk.events_pending():
                 gtk.main_iteration(False)
            time.sleep(.8)
            self.textbuffer.remove_tag(helpcolor, self.textbuffer.get_iter_at_offset(i), self.textbuffer.get_iter_at_offset(i+1))
        #Re-highlight the current letter on the keyboard)  
        self.highlight_curr_letter()
        self.handler_unblock(self.keyboard_trigger)

    #Highlights the current letter on the keyboard        
    def highlight_curr_letter(self):
        letter = self.inputString[self.currChar]
        self.keyboard.highlightkey(letter)

    #loads a set of dipthongs from dipthongs.dpt. When we run across one of those dipthongs
    #we will wait and try to play the dipthong sound instead.
    def loadDipthongs(self):
        self.dip_list = []
        try:
            lessonFile = file(TYPING_ROOT+os.sep+"dipthongs.dpn","r")         
        except IOError, error:            
            print "unable to read file %s : %s" % (TYPING_ROOT+os.sep+"dipthongs.dpn", error)
            print "if you believe the user should have memory, please error-check."
            return

        lineInput = lessonFile.readline()
        if lineInput.find("\n") != -1:
            lineInput = lineInput[0:lineInput.find("\n")]
        while lineInput != '':
            #Make sure we only get dipthongs of length exactly 2
            if(len(lineInput) == 2):
                self.dip_list.append(lineInput)
            lineInput = lessonFile.readline()
            if lineInput.find("\n") != -1:
                lineInput = lineInput[0:lineInput.find("\n")]
        
    #Build the final reward screen: choose a random reward image, setup the certificate
    def makeRewards(self):
        self.rewardscreen = gtk.Table(10, 10, True)
        rewardpicframe = gtk.Frame()
        rewardpic = gtk.Image()
        rewardNum = random.randint(1,7)
        rewardpicbuf = gtk.gdk.pixbuf_new_from_file((TYPING_ROOT + os.sep + "images" + os.sep + "reward" + os.sep + "reward%s.gif") % (rewardNum)).scale_simple(250, 250, gtk.gdk.INTERP_BILINEAR)
        rewardpic.set_from_pixbuf(rewardpicbuf)
        rewardpic.show()
        rewardpicframe.add(rewardpic)
        rewardpicframe.show()
        
        self.rewardlessonframe = gtk.Frame()
        self.rewardlessonframe.show()
        
        rewardcertframe = gtk.Frame()
        rewardcertpic = gtk.Image()
        rewardcertpicbuf = gtk.gdk.pixbuf_new_from_file(TYPING_ROOT + os.sep + "images" + os.sep + "reward" + os.sep + "certificate.gif").scale_simple(120, 120, gtk.gdk.INTERP_BILINEAR)
        rewardcertpic.set_from_pixbuf(rewardcertpicbuf)
        rewardcertpic.show()
        rewardcertframe.add(rewardcertpic)
        rewardcertframe.show()
        
        self.rewardscreen.attach(rewardpicframe, 3, 7, 0, 5)
        self.rewardscreen.attach(self.rewardlessonframe, 1, 4, 6, 9)
        self.rewardscreen.attach(rewardcertframe, 6, 9, 6, 9)
        self.rewardscreen.hide()
     
            
    #Loads up the words for a given lesson into memory
    #returns false if given a bad lesson name, and doesn't set variables
    def startLesson(self, lessonName):
        self.lessonWords = self.lessonPlan.getLessonWords(lessonName)
        if(self.lessonWords == {}):
            return False
        self.wordNum = 0
        self.currentWord = ""
        self.playWord = ""
        self.goThree = False
        return True

    #Displays an image in the image buffer, so the user can associate an image with the word they are typing
    def showImage(self, imageName, showWord):
        if (imageName == None):
            self.imagetext.get_buffer().set_text("")
            return  
            
        try:
            file_check = file(IMAGE_SOURCE + os.sep +  self.lessonChosen + os.sep + imageName + ".gif")
        except IOError, error:
            return False
 
        buffer = self.imagetext.get_buffer()

        #If the image isn't given text (as in assessment mode), we make the image bigger        
        if(showWord):
            buffer.set_text(imageName + "\n")
            buffer.apply_tag(buffer.get_tag_table().lookup("size"), buffer.get_start_iter(), buffer.get_end_iter())
            buffer.apply_tag(buffer.get_tag_table().lookup("color"), buffer.get_start_iter(), buffer.get_end_iter())
            picsize = 100
        else:
            buffer.set_text("\n")
            picsize = 125
        
        pixbuf = gtk.gdk.pixbuf_new_from_file(IMAGE_SOURCE + os.sep +  self.lessonChosen + os.sep +  imageName + ".gif").scale_simple(picsize, picsize, gtk.gdk.INTERP_BILINEAR)
        
        buffer.insert_pixbuf(buffer.get_end_iter(), pixbuf)
        self.imagetext.show()

    #Checks to see if the current character is the next one we 
    #we expecting.  If so, advances the expecting.  Does nothing, for
    #now, on bad input
    #Also, plays sound for the character if it was the right one
    #And, if we reached the end of a word (defined by hitting space),
    #plays a sound for the word if one exists
    def isRight(self, widget, event):
        #This will make sure it only works while the current character is a valid place
        #In the expected input.  This should never fail.
        if(self.currChar < len(self.inputString)):
            #Check if the correct letter was pressed
            if(event.string == self.inputString[self.currChar]):
                self.doRightStroke(widget, event)
            #Plays the "click" sound if we hit the wrong key.
            else:
                soundPlay = sound.Sound()
                soundPlay.setSound(TYPING_ROOT + os.sep + "sounds" + os.sep + "click_error")
                soundPlay.run()
                self.highlight_curr_letter()
        return True

    def doRightStroke(self, widget, event):
        soundPlay = sound.Sound()
        #CHeck to see if we were expecting a dipthong.
        #If we are, we want to play its sound.
        #If not, we need to check to see if this is the start of a dipthong, and wait
        #If not, we need to play this letter.
        if(self.dip_waiting):
            #sounds are lower case.
            soundPlay.setSound(TYPING_ROOT + os.sep + "sounds" + os.sep + self.dip_letter+self.inputString[self.currChar].lower())
            self.dip_waiting = False
            self.dip_letter = ""
        else:
            if(self.isDipthong()):
                self.dip_waiting = True
                self.dip_letter = self.inputString[self.currChar].lower()
            else:
                #sounds are lower case.
                soundPlay.setSound(TYPING_ROOT + os.sep + "sounds" + os.sep + self.inputString[self.currChar].lower())
        
                
        #see if we ended a word.  If so, try to play it.  
        if(self.currChar + 1 == len(self.inputString) or self.inputString[self.currChar+1] == " "):
            #If we just ended the string, our word to play needs the current character.
            #If not (e.g., we hit a space), we already have the full right word.
            if(event.string != " "):
                self.playWord = self.playWord + event.string
            if(self.playEnds):
                soundPlay.setSound2(TYPING_ROOT + os.sep + "sounds" + os.sep + self.playWord.lower())
            self.showImage(self.playWord.lower(),True)
            self.playWord = ""
        #If not, append this character to the word
        elif(event.string != " "):
            self.playWord = self.playWord + event.string
        soundPlay.run()
            
        #Remove the underline, color from the current letter, and recolor it black.                
        self.tag_curr_char(self.undertag,False)
        self.tag_curr_char(self.magentatag, False)
        self.tag_curr_char(self.redtag, False)

        #Advance the character                
        self.currChar = self.currChar + 1

        #underline the next expected character.                
        self.tag_curr_char(self.undertag, True)
        if(self.currChar == len(self.inputString)):
            gtk.main_quit()
            #quitting will advance the code in runGame, thus choosing the next word
        else:
            self.highlight_curr_letter()
            #Make sure the keyboard display the next letter to type
        return True

    #Check to see if the character just typed is the start of a dipthong.
    #Makes sure that there is at least one more character, then, cycles all possible
    #dipthongs, seeing if this+next char is one of them.
    #Returns true if so, false if no more characters or no dipthong matches.
    def isDipthong(self):
        if(self.currChar +1 == len(self.inputString)):
            return False 
        potentialDip = self.inputString[self.currChar].lower()+self.inputString[self.currChar+1].lower()
        for x in range(0,len(self.dip_list)):
            if(self.dip_list[x] == potentialDip):
                return True
        return False

    #Creates the next full string the user will have
    #to type.
    def getNextQuiz(self):
        quizString = self.getNextWord()

        #NextWord returns "" only if out of words
        #So we must be done with the lesson
        if(quizString == ""):
            return False
       
        self.inputString = quizString

        #Set up which character number we are expecting (the 0th index, or first character)        
        self.currChar = 0
        return True

    #Figures out what the next word will be.  Every 3 words, reviews the last 3 words
    #Returns "" if there are no more words.
    def getNextWord(self):
        #Check to see if we are at the (3n)th word, and if we need to do a 3 word  review
        if(self.wordNum % 3 == 0) and self.goThree:
            self.goThree = False
            self.getThreeWordReview(self.lessonWords[self.wordNum - 1], self.lessonWords[self.wordNum - 2], self.lessonWords[self.wordNum - 3])
        #Otherwise, just gets the next word
        else:
            #See if this word was in memory.  If so, remove the underlining.
            try:
                toClear = self.memoryLabels[(self.wordNum, self.lessonChosen)]
                toClear.set_pattern("")
            except KeyError:
                True
            
            self.wordNum = int(self.wordNum) + 1
            #Reset the need to do a three-word review.  Was only false immediately after such a review
            self.goThree = True
                    
            #If there are no more words, return the empty string            
            if(self.wordNum > len(self.lessonWords)) :
                self.currentWord = ""
                return self.currentWord
            #Otherwise, get the next word
            else:
                self.currentWord = self.lessonWords[self.wordNum - 1]

            #See if this word is in memory.  If so, underline it
            try:
                toSet = self.memoryLabels[(self.wordNum, self.lessonChosen)]
                pattern = ""
                for x in range(0,len(toSet.get_text())):
                    pattern = pattern + "_"
                toSet.set_pattern(pattern)
            except KeyError:
                True

        #Return the next word
        return self.currentWord

    #Creates a review of 3 words, in a random order
    def getThreeWordReview(self, word1, word2, word3):
        wordset = []
        wordset.append(word1)
        wordset.append(word2)
        wordset.append(word3)
        
        firstReview = random.randint(0,2)
        firstReview = wordset[firstReview]
        wordset.remove(firstReview)
        
        secondReview = random.randint(0,1)
        secondReview = wordset[secondReview]
        wordset.remove(secondReview)

        thirdReview = wordset[0]
                
        self.currentWord = firstReview+" "+secondReview+" "+thirdReview

    #Create the text prompt box, so the user can see what to type.
    def create_text_prompt(self, scrolledWindow):
        scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        textview = gtk.TextView()
        #As the view is to be uneditable, hid the cursor.  Center the text, too        
        
        textview.set_cursor_visible(False)
        textview.set_justification(gtk.JUSTIFY_CENTER)
        textview.set_editable(False)
        
        self.textbuffer = textview.get_buffer()
        scrolledWindow.add(textview)
        scrolledWindow.show()
        textview.show()

        #Set starting text blank        
        self.setup_next_word("")

        #Create various tags for size, underline, color, to change display later
        self.sizetag = self.textbuffer.create_tag()
        self.sizetag.set_property("size-points", 32)
        self.redtag = self.textbuffer.create_tag(foreground="red")
        self.magentatag = self.textbuffer.create_tag(foreground="magenta")
        self.undertag = self.textbuffer.create_tag(underline=True)
        helpcolortag = gtk.TextTag("helpcolor")
        helpcolortag.set_property("foreground", "green")
        self.textbuffer.get_tag_table().add(helpcolortag)

    #Sets up a word to prompt the user for.
    #Highlights the letters magenta or red based on the side of the keyboard they are on
    def setup_next_word(self, toDisplay):
        self.textbuffer.remove_all_tags(self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
        self.textbuffer.set_text(toDisplay)
        oldChar = self.currChar
        self.currChar = 0
        leftChars = "qwertasdfgzxcvbQWERTASDFGZXCVB12345~'!@#$%"
        for x in range (0, len(toDisplay)):
            if(x >= oldChar):
                if(leftChars.find(toDisplay[x]) != -1):
                    self.tag_curr_char(self.redtag,True)
                else:
                    self.tag_curr_char(self.magentatag,True)
            self.currChar = self.currChar + 1
        self.currChar = oldChar

    #Applies or removes a tag from a the current expected character.
    #Applies if Apply is True, removes if False.
    def tag_curr_char(self, tag, apply):
        start = self.textbuffer.get_iter_at_offset(self.currChar)
        end = self.textbuffer.get_iter_at_offset(self.currChar+1)
        if(apply):
            self.textbuffer.apply_tag(tag,start, end)
        else:
            self.textbuffer.remove_tag(tag,start, end)

    #Displays the image for the current word beneath that image.            
    def disp_curr_word(self, word):
        if (word == None):
            return  
            
        try:
            file_check = file(IMAGE_SOURCE + os.sep +  self.lessonChosen + os.sep + word + ".gif")
        except IOError, error:
            return False
        
        pixbuf = gtk.gdk.pixbuf_new_from_file(IMAGE_SOURCE + os.sep +  self.lessonChosen + os.sep +  word + ".gif").scale_simple(90, 90, gtk.gdk.INTERP_BILINEAR)
        
        self.textbuffer.insert(self.textbuffer.get_end_iter(), "\n")
        self.textbuffer.insert_pixbuf(self.textbuffer.get_end_iter(), pixbuf)
        self.show()
        
    #Called if the window is closed.  Sets self.quit to True, to also call other window delete events
    def delete_event(self, widget, event, data = None):
        self.quit = True
        self.quit_game()

    #Goes back.  Also quits, but doesn't set self.quit to True, so that we keep the program running
    def back(self, widget, data=None):
        if(not self.initialrun):
            self.quit = False
            self.quit_game()

    #Sets abort to true, stopping the "waiting for input" cycle.    
    def quit_game(self):
        self.abort = True
        gtk.main_quit()

    #Restores the lesson plan to starting at the chosen word in the memory sequence.
    def memoryCallback(self, widget, event, wordNum):
        #Clear underlining of the current word in memory
        try:
             toClear = self.memoryLabels[(self.wordNum, self.lessonChosen)]
             toClear.set_pattern("")
        except KeyError:
             True
             
        self.wordNum = wordNum - 1
        self.currentWord = self.lessonWords[self.wordNum - 1]
        self.goThree = False
        self.getNextQuiz()
        self.setup_next_word(self.inputString)
        self.textbuffer.apply_tag(self.sizetag, self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
        self.tag_curr_char(self.undertag, True)
        self.showImage(self.inputString, True)
        self.highlight_curr_letter()
        self.progressBar.set_fraction((self.wordNum-1.0)/len(self.lessonWords))

    #Determines if a word is contained in our memory.  Returns true if it is, false otherwise        
    def memContains(self, word):
        keys = self.memoryLabels.keys()
        for x in keys:
            if(x[1] == self.lessonChosen):
                if(self.memoryLabels[x].get_text() == word):
                    return True
        return False

    #Displays the final reward screen, including playing a cheer and the lesson image
    def displayReward(self):
        self.rewardlessonpic = gtk.Image()
        self.rewardlessonframe.add(self.rewardlessonpic)
        picbuf = gtk.gdk.pixbuf_new_from_file(TYPING_ROOT + os.sep + "images" + os.sep + "lessons" + os.sep + "chooser" + os.sep + self.lessonChosen + ".gif").scale_simple(120, 120, gtk.gdk.INTERP_BILINEAR)
        #print picname
        self.rewardlessonpic.set_from_pixbuf(picbuf)
        self.rewardlessonpic.show()
        self.rewardscreen.show()
        self.container.show()

        rewardNum = random.randint(1,4)        
        soundPlay = sound.Sound()
        soundPlay.setSound(TYPING_ROOT + os.sep + "sounds" + os.sep + "reward" + os.sep + "cheer%i" % (rewardNum)) 
        soundPlay.run()
        
        while gtk.events_pending():
            gtk.main_iteration(False)
        time.sleep(5)
        

    #Starts up the game for a given lesson 
    def runGame(self, lessonLetter):
        #Reset progress variables
        self.progressBar.set_fraction(0.0)
        self.dip_waiting = False
        self.dip_letter = ""
        
        self.handler_unblock(self.keyboard_trigger)
        #Grab focus, so all widget events start here
        self.grab_add()
       
        self.rewardscreen.hide()
        self.table.show()
        
        self.quit = False
        self.abort = False
        self.lessonChosen = lessonLetter
        
        #Make sure we received a valid letter in
        if(not self.startLesson(self.lessonChosen)):
            print "Error!  Invalid Lesson"
            return False
      
        #Clear away all memory elements not associated with this lesson
        keys = self.memoryLabels.keys()
        for x in keys:
            if(x[1] != self.lessonChosen):
                self.memoryLabels[x].get_parent().hide()
            else:
                self.memoryLabels[x].get_parent().show()
              

        #Connect event for the closing of a window
        self.deleter = self.win.connect("delete_event", self.delete_event)
        
        self.initialrun = True
  
        #Keep going until we run out of words to quiz on
        while(self.getNextQuiz()):
 
            #Display the next query string  
            self.setup_next_word(self.inputString)
            self.textbuffer.apply_tag(self.sizetag, self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter())
            self.tag_curr_char(self.undertag, True)
            self.disp_curr_word(self.inputString)
            self.highlight_curr_letter()

            #For the first word, we automatically show help            
            if (self.initialrun):
                self.showImage(None, False)
                self.helpdisplay(None)
                self.initialrun = False
                
            #Start up and wait for the keyboard
            gtk.main()   
            if(self.abort):
                #Stop grabbing focus, so widget events will start as normal
                self.grab_remove()
                self.memoryFiles.writeMem(self.memoryLabels)
                if(not self.quit):
                    self.handler_block(self.keyboard_trigger)
                return self.quit
            
            #Update our progress through the lesson, making sure to never have more than 1.0 progress
            if(self.progressBar.get_fraction() + (3.0 / (4.0*len(self.lessonWords))) < 1.0):
                self.progressBar.set_fraction(self.progressBar.get_fraction() + (3.0 / (4.0*len(self.lessonWords))))
            else:
                self.progressBar.set_fraction(1.0)


            if(self.goThree and not self.memContains(self.currentWord)):
                self.memory.append(self.currentWord)
                EBox = gtk.EventBox()
                self.membox.pack_start(EBox, False, True, 5)
                EBox.show()
                Lab = gtk.Label(self.currentWord)
                EBox.connect("button-press-event", self.memoryCallback, self.wordNum)
                EBox.add(Lab)
                self.memoryLabels[(self.wordNum, self.lessonChosen)] = Lab
                Lab.show()
        
        self.table.hide()
                
        #De-link the keyboard from input
        self.handler_block(self.keyboard_trigger)

        self.displayReward()

        #Disconnect the delete event, so things work correctly above.        
        self.win.disconnect(self.deleter)

        #Stop grabbing focus, so widget events will start as normal        
        self.grab_remove()
        self.memoryFiles.writeMem(self.memoryLabels)
        return False